我有一个用户可以更新其详细信息的表单。此更新通过使用jQuery focusout函数和Ajax来更新数据库来完成。
在这个例子中,我有三个文本输入。我测试了用户进入下一个输入时更新的第一个输入。正在更新输入时出现加载程序图标。
对于第一个输入,我创建了一个控制器及其相应的JQuery代码。
但是,如果我有一个10输入的形式,我将不得不这样做10次。我的问题是:我如何简化这个?所以我只需要编码一次。
以下是表格:
<form role="form" class="form-horizontal" action="{{URL::route('user-edit-profile-post2')}}" method="post" id="formedit2">
<!---------------------------SECCIÓN USUARIOS---------------------->
<!-----Nombre de pila---------->
<div class="form-group @if ($errors->has('nombre_pila')) has-error @endif">
<label for="nombre_pila" class="col-sm-2 control-label">Nombre(s) de pila:</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="nombre_pila" name="nombre_pila" maxlength="45" value="@if(Input::old('nombre_pila')){{e(Input::old('nombre_pila'))}}@elseif(isset($nombrepila)){{$nombrepila}}@endif">
</div>
@if($errors->has('nombre_pila'))
<p class="help-block">{{$errors->first('nombre_pila')}}</p>
@endif
</div><!-- ----------fin nombre de pila ------------ -->
<div class="form-group @if ($errors->has('ap_paterno')) has-error @endif"><!--apellido paterno-->
<label for="ap_paterno" class="col-sm-2 control-label">Apellido paterno:</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="ap_paterno" name="ap_paterno" maxlength="45" value="{{ (Input::old('ap_paterno') ? e(Input::old('ap_paterno')) : (isset($ap_paterno) ? $ap_paterno : '')) }}"><!--Referencias: https://stackoverflow.com/questions/26960929/laravel-4-when-i-retrieve-info-from-database-into-input-text-1-extra-space-is-a/26961224?noredirect=1#comment42683960_26961224-->
</div>
@if($errors->has('ap_paterno'))
<p class="help-block">{{$errors->first('ap_paterno')}}</p>
@endif
</div><!-- ----------fin de apellido paterno ------------ -->
<div class="form-group @if ($errors->has('ap_materno')) has-error @endif"><!--apellido materno-->
<label for="ap_materno" class="col-sm-2 control-label">Apellido materno:</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="ap_materno" name="ap_materno" maxlength="45" value="@if(Input::old('ap_materno')){{e(Input::old('ap_materno'))}}@elseif(isset($ap_materno)){{$ap_materno}}@endif">
</div>
@if($errors->has('ap_materno'))
<p class="help-block">{{$errors->first('ap_materno')}}</p>
@endif
</div><!-- ----------fin de apellido paterno ------------ -->
<!------------------GUARDAR--------------------- -->
<div class="form-group"><!--Botón de guardar-->
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Guardar</button>
</div>
</div><!--Fin del botón de guardar-->
<!--------------Fin de GUARDAR ---------------->
<!--TOKEN-->
{{ Form::token() }}
</form>
在表单下面,我有这个JQuery代码:
<script type="text/javascript">
$('#nombre_pila').on('focusout',function(){
var editform = $('#formedit2').serializeArray();
var url = $("#formedit2").attr('action');//con esto se llama al controlador correspondiente!
$('#nombre_pila').addClass('loadinggif');
$.post(url, editform, function(data,status){
$('#nombre_pila').removeClass('loadinggif');
//alert(data);
if(data=='fail'){
alert('No se pudo actualizar el campo. Status:' + status);
}else if(data=='success'){
alert('Dato actualizado exitosamente! Status: ' + status);
}else if(status=='timeout'){
alert('El tiempo de espera se ha agotado. Recargue la página.');
}
});
});
</script>
控制器是:
public function postEditProfile2(){
//save data and send to form page or display a success message
//instanciando al usuario actual:
$id_user=Auth::user()->id;
$usuario=User::find($id_user);
$nombre_pila=Input::get('nombre_pila');
//preparando el dato para guardarlo
$usuario_data=array(
'nombre_pila'=>Input::get('nombre_pila')
);
// saving...
$usuario->fill($usuario_data);
if($usuario->save()){
return 'success';
}else{
return 'fail';
}
return 'posted: '.$nombre_pila;
}
到目前为止,我有这个代码来更新焦点输出的第一个输入 nombre_pila 。现在我还剩下两个输入: ap_paterno 和 ap_materno 。如何安排我的代码,以便更新已经集中注意的最新输入的信息?
修改:
我想要的是只更新每个输入。为了达到这个目的,我已经在每个输入中设置了标识符,这样我可以轻松地获得最近聚焦的输入。但首先我需要检测输入文本中的值是否已更改(在此编辑表单中,每个输入显示先前从用户保存在数据库中的数据)。
因此,在聚焦功能之前,我添加了另一个函数来检测特定输入的变化(通过其ID属性),就像在fiddle中一样。最后,我决定不在这里使用focusout(),因为它结果令人讨厌,特别是如果你把鼠标放在任何输入中,post()函数将不可避免地调用,例如,即使我去另一个窗口或另一个标签。
所以这里是JQuery的编辑部分,它运行正常,它只在数据库中更新相应的输入值:
//Primero detectar si hubo cambios en un input dado
var timerid;
$("input").on("input",function(e){
var currentId = $(this).attr('id');
//alert('Current ID value is: '+currentId);
var value = $(this).val();
//preguntar si el dato del input en donde está el cursor ha cambiado:
if($(this).data('lastval')!=value){
$(this).data('lastval',value);
nuevoValor=$(this).val();
clearTimeout(timerid);
timerid=setTimeout(function(){
//change action
alert('vamos a actualizar la info...Identificador: '+currentId+' Nuevo valor:'+nuevoValor);
//AQUÍ PONEMOS EL PROCEDIMIENTO DE ACTUALIZACIÓN DE LA INFO DEL CAMPO CORRESPONDIENTE.
//var currentID = $('#formedit2 input').attr('id');//https://stackoverflow.com/a/23266812/1883256, http://jsfiddle.net/xstqLkz4/59/, http://www.tequilafish.com/2007/12/04/jquery-how-to-get-the-id-of-your-current-object/
//var newValue = $(currentId).val();
alert('ID es: '+currentId+' and current value is: '+nuevoValor);
//var editform = {identifier:currentID,value:newValue};
var editform = $('#formedit2').serializeArray();
editform.push({name:'identifier',value:currentId});//https://stackoverflow.com/a/13362942/1883256
//alert(editform);
var url = $("#formedit2").attr('action');//con esto se llama al controlador correspondiente!
$(this).addClass('loadinggif');
$.post(url, editform, function(data,status){
$('#formedit2 input').removeClass('loadinggif');
//alert(data);
if(data=='fail'){
alert('Could not update the input field. Status:' + status);
$('#formedit2 input').removeClass('loadinggif');
}else if(data=='success'){
alert('Data updated successfully! Status: ' + status);
$('#formedit2 input').removeClass('loadinggif');
}else if(status=='timeout'){
alert('Time out. Please reload');
$('#formedit2 input').removeClass('loadinggif');
}else if(status=='error'){
alert('There has been an error. Try again later.');
$('#formedit2 input').removeClass('loadinggif');
}else{
$('#formedit2 input').removeClass('loadinggif');
alert(data);
}
});//end of post() function
//END OF UPDATING INFO PROCESS
},2500);
};
});//end of input part
这里是控制器,通过使用switch语句,控制器知道必须在数据库中更新哪个字段:
public function postEditProfile2(){
//save data and send to form page or display a success message
//instanciando al usuario actual:
$id_user=Auth::user()->id;
$usuario=User::find($id_user);
$identifier=Input::get('identifier');
//$nombre_pila=Input::get('nombre_pila');
$identificando=explode('_',$identifier);
$tabla=$identificando[0];
$num=end($identificando);
if($tabla=='usuario'){
switch ($num) {
case '01':
$usuario_data=array('nombre_pila'=>Input::get('nombre_pila'));
break;
case '02':
$usuario_data=array('ap_paterno'=>Input::get('ap_paterno'));
break;
case '03':
$usuario_data=array('ap_materno'=>Input::get('ap_materno'));
break;
default:
# code...
break;
}
// saving...*/
$usuario->fill($usuario_data);
/*$usuario->fill(Input::all());*/
if($usuario->save()){
return 'success';
}else{
return 'fail';
}
}else{
return 'error';
}
}//end of postEditProfile2() function
但现在的问题是ajax-loader.gif,我把它作为一个类添加的部分,$(this).addClass('loadinggif');
不再出现。为什么?有什么帮助吗?
解决: 我没有正确地为ajax加载器使用选择器,它是一个缺少的简单+符号,如here所示,所以该行是:
$('#'+currentId).addClass('loadinggif');
最后的问题: 剩下的唯一问题是不会出现超时状态。例如,如果一小时没有任何操作,我尝试修改数据,没有任何反应。什么都没有更新。所以我必须再次刷新页面。这在Stackoverflow中不会发生,即使计算机已经“休眠”并且我再次唤醒它,我仍然可以在不刷新页面的情况下更新信息。怎么可能?在我的情况下,我该如何保持页面活着?
答案 0 :(得分:1)
我希望我理解你...
首先,使您的jQuery代码通用,以便它适用于每个输入。您需要做的就是更改选择器:
$('#formedit2 input[type=text]').on('focusout',function(){
var editform = $('#formedit2').serializeArray();
var url = $("#formedit2").attr('action');//con esto se llama al controlador correspondiente!
$(this).addClass('loadinggif');
$.post(url, editform, function(data,status){
$(this).removeClass('loadinggif');
//alert(data);
if(data=='fail'){
alert('No se pudo actualizar el campo. Status:' + status);
}else if(data=='success'){
alert('Dato actualizado exitosamente! Status: ' + status);
}else if(status=='timeout'){
alert('El tiempo de espera se ha agotado. Recargue la página.');
}
});
});
正如您所看到的,我更改了第一个选择器以匹配所有文本输入,并将nombre_pila
引用的$(this)
替换为fillable/guarded
。
之后,稍微更改控制器,以便填充传递给模型的任何输入。只需确保在模型中设置public function postEditProfile2(){
$id_user=Auth::user()->id;
$usuario=User::find($id_user);
$usuario->fill(Input::all());
if($usuario->save()){
return 'success';
}else{
return 'fail';
}
}
属性即可。
{{1}}
(我也删除了最后一个返回语句,因为它永远不会到达)